/*
 * Copyright (C) GSX Techedu Inc. All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 */

package com.nime.novel.crawl.core.list;

import com.nime.novel.crawl.constant.ChannelEnum;
import com.nime.novel.crawl.constant.CrawConstant;
import com.nime.novel.crawl.constant.StatusEnum;
import com.nime.novel.crawl.domain.CrawlUrl;
import com.nime.novel.crawl.mapper.CrawlSourceMapper;
import com.nime.novel.crawl.service.CrawlUrlService;
import com.nime.novel.crawl.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author liujialiang
 * @description 生成列表的URL
 * @team wuhan operational dev.
 * @date 2020/8/28 11:03 下午
 **/
@Slf4j
public abstract class UrlGenService {

    @Autowired
    protected CrawlUrlService crawlUrlService;

    protected abstract CrawlUrl getNewestUrl(Integer policyId);

    protected abstract List<String> parseUrl(String html);

    @Autowired
    private CrawlSourceMapper crawlSourceMapper;

    public void start(Integer policyId) {
        CrawlUrl crawl = getNewestUrl(policyId);
        if (null == crawl) {
            return;
        }
        // 更新标识 爬取中 避免重复爬取
        crawlUrlService.updateStatus(crawl.getId(), StatusEnum.DOING.getCode());
        StatusEnum statusEnum = process(crawl) ? StatusEnum.DONE : StatusEnum.FAIL;
        crawlUrlService.updateStatus(crawl.getId(), statusEnum.getCode());
    }

    protected abstract boolean saveNewUrlList(CrawlUrl crawlUrl, List<String> urlList)
        throws Exception;

    /**
     *
     *
     * @param policyId
     * @param referId   来源页面ID
     * @param url       生成的URL
     * @param channel   频道ID
     * @return
     */
    protected Long insert(Integer policyId, Long referId, String url, ChannelEnum channel) {
        String urlHash = DigestUtils.md5Hex(url);
        CrawlUrl old = crawlUrlService.getByUrlHash(urlHash);
        if (old != null) {
            return null;
        }
        CrawlUrl entity = CrawlUrl.builder()
            .url(url)
            .channel(channel.getCode())
            .policyId(policyId)
            .crawlStatus(StatusEnum.TODO.getCode())
            .urlHash(urlHash)
            .referId(referId)
            .build();
        crawlUrlService.create(entity);
        // 查询父页面
        CrawlUrl pu = crawlUrlService.getById(entity.getReferId());
        String routPrefix = null == pu ? "0" : pu.getRoute();
        crawlUrlService.updateRoute(entity.getId(), routPrefix + "-" + entity.getId());
        return entity.getId();
    }

    private boolean process(CrawlUrl crawlUrl) {
        String htmlText = HttpUtil.getByHttpClient(crawlUrl.getUrl());
        if (StringUtils.isEmpty(htmlText)) {
            return false;
        }
        // 解析获取新生成的url
        List<String> urlList = parseUrl(htmlText);
        try {
            saveNewUrlList(crawlUrl, urlList);
        } catch (Exception e) {
            log.info("url 存储异常 e-> {}", e.getMessage());
            return false;
        }
        return true;
    }
}
